﻿#include "study12.h"
// C/C++ 标准库学习网站：https://legacy.cplusplus.com
// C/C++ 微软(Visual Studio)中文学习网站：https://learn.microsoft.com/zh-cn/cpp/cpp/?view=msvc-170

class Entity {
public:
	Entity(const MyString& name)
		: m_name(name) {
	}
	Entity(MyString&& name) noexcept
		: m_name((MyString&&)(name)) {
	} // 移动构造函数，MyString&& 参数表示将 name 转移到新对象中，可替换为 std::move，说明显示调用调用右值引用构造函数（移动构造函数）

	void print_name() { m_name.print_str(); }
private:
	MyString m_name;
};

void test_move_semantics() {
	using namespace std;

	/*MyString s1("hello");
	s1.print_str();
	//"const string" + s1; // err: 不能将 const 字符串不能转移到右值
	s1 + " world";
	MyString s2 = s1;
	s2 + " again " + s1;
	s2.print_str(); */

	Entity e1("测试移动语义字符串");
	e1.print_name();
	Entity e2(move(e1)); // 移动语义，将 e1 的所有资源转移到 e2 中
	e2.print_name();
	cout << "-------------------------------------------------------------------\n";

	MyString s1("测试移动操作符字符串");
	MyString s2/* = move(s1)*/; // 注释表示移动构造函数，将 s1 的所有资源转移到 s2 中
	cout << "移动前的 s1 字符串：";
	s1.print_str();
	cout << "移动前的 s2 字符串：";
	s2.print_str();

	s2 = move(s1); // 移动赋值操作符，相当于 s2.operator=(move(s1))，将 s1 的所有资源转移到 s2 中
	cout << "移动后的 s1 字符串：";
	s1.print_str();
	cout << "移动后的 s2 字符串：";
	s2.print_str();
}